import { EventEmitter } from 'events';
import { ErrorDetails } from '../types/services';

export class AppError extends Error {
  code: string;
  context?: Record<string, unknown>;

  constructor(message: string, code?: string, context?: Record<string, unknown>) {
    super(message);
    this.name = 'AppError';
    this.code = code || 'INTERNAL_ERROR';
    this.context = context;
    Error.captureStackTrace(this, this.constructor);
  }
}

class ErrorHandler extends EventEmitter {
  private static instance: ErrorHandler;
  private errorLog: ErrorDetails[] = [];
  private maxLogSize = 1000;

  private constructor() {
    super();
  }

  static getInstance(): ErrorHandler {
    if (!ErrorHandler.instance) {
      ErrorHandler.instance = new ErrorHandler();
    }
    return ErrorHandler.instance;
  }

  handleError(error: Error | AppError, context?: Record<string, unknown>): void {
    const errorDetails: ErrorDetails = {
      code: error instanceof AppError ? error.code : 'INTERNAL_ERROR',
      message: error.message,
      stack: error.stack,
      context: {
        ...(error instanceof AppError ? error.context : {}),
        ...context
      }
    };

    this.logError(errorDetails);
    this.emit('error', errorDetails);
  }

  private logError(details: ErrorDetails): void {
    this.errorLog.unshift(details);
    if (this.errorLog.length > this.maxLogSize) {
      this.errorLog.pop();
    }
  }

  async getLastErrors(limit = 10): Promise<ErrorDetails[]> {
    return this.errorLog.slice(0, limit);
  }

  clearErrors(): void {
    this.errorLog = [];
  }

  setMaxLogSize(size: number): void {
    this.maxLogSize = size;
    if (this.errorLog.length > size) {
      this.errorLog = this.errorLog.slice(0, size);
    }
  }
}

export const errorHandler = ErrorHandler.getInstance();
